package br.unifesp.lma.chamada.controller.web;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import javax.servlet.http.HttpSession;

import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;

import br.unifesp.lma.chamada.controller.form.DisciplinaAlunoForm;
import br.unifesp.lma.chamada.dao.AlunoDAO;
import br.unifesp.lma.chamada.dao.AulaDAO;
import br.unifesp.lma.chamada.dao.DisciplinaDAO;
import br.unifesp.lma.chamada.dao.ProfessorDAO;
import br.unifesp.lma.chamada.model.embed.AlunoDisciplina;
import br.unifesp.lma.chamada.model.embed.AlunoPresenca;
import br.unifesp.lma.chamada.model.entity.Aluno;
import br.unifesp.lma.chamada.model.entity.Aula;
import br.unifesp.lma.chamada.model.entity.Disciplina;
import br.unifesp.lma.chamada.model.entity.Professor;

@RequestMapping(value = "/web")
@Controller
public class DisciplinaController {

	private static Logger log = Logger.getLogger(DisciplinaController.class);

	@Autowired
	private DisciplinaDAO disciplinaDAO;

	@Autowired
	private ProfessorDAO professorDAO;

	@Autowired
	private AlunoDAO alunoDAO;

	@Autowired
	private AulaDAO aulaDAO;

	@RequestMapping(value = "remover-disciplina", method = RequestMethod.GET)
	public String removerDisciplina(Model uiModel, Long id) {

		Disciplina disciplina = disciplinaDAO.get(id);
		disciplinaDAO.delete(disciplina);

		return "redirect:/web/listar-disciplinas";
	}

	@RequestMapping(value = "editar-disciplina", method = RequestMethod.GET)
	public String editarDisciplina(Model uiModel, Long id) {

		Disciplina disciplina = disciplinaDAO.get(id);
		uiModel.addAttribute("active", "disciplinas");
		uiModel.addAttribute("disciplina", disciplina);
		return "editar-disciplina";
	}

	@RequestMapping(value = "adicionar-disciplina", method = RequestMethod.POST)
	public String salvarDisciplina(HttpSession session, Model uiModel, Disciplina disciplina) {

		Long professorId = ((Long) session.getAttribute("professorId"));
		disciplina.setProfessorId(professorId);
		disciplinaDAO.put(disciplina);

		return "redirect:/web/listar-disciplinas";
	}

	@RequestMapping(value = "adicionar-disciplina", method = RequestMethod.GET)
	public String adicionarDisciplina(Model uiModel) {
		List<Professor> professores = professorDAO.getAll();

		uiModel.addAttribute("disciplina", new Disciplina());
		uiModel.addAttribute("professores", professores);
		uiModel.addAttribute("active", "disciplinas");
		return "form-disciplina";
	}

	public AlunoPresenca getAlunoPresenca(List<AlunoPresenca> aulas, Long id, Aula aula) {
		for (AlunoPresenca ap : aulas) {
			if (ap.getIdAluno() == id)
				return ap;
		}
		AlunoPresenca alunoPresenca = new AlunoPresenca();
		alunoPresenca.setIdAluno(id);
		alunoPresenca.setPresente(false);
		aula.getPresencas().add(alunoPresenca);
		return alunoPresenca;
	}

	public boolean getAlunoId(Long[] alunosIds, Long id) {
		for (int i = 0; i < alunosIds.length; i++) {
			if (alunosIds[i].equals(id)) {
				return true;
			}
		}

		return false;

	}

	public void deleteAlunoPresenca(List<AlunoPresenca> aulas, Long[] alunosIds, Aula aula) {
		AlunoPresenca aux;

		for (int i = 0; i < aulas.size(); i++) {
			aux = aulas.get(i);

			if (getAlunoId(alunosIds, aux.getIdAluno()) == false) {
				log.debug("remove aluno " + aux.getIdAluno());
				aulas.remove(aux);
				log.debug("remove aluno " + aux.getIdAluno());
			}
		}
	}

	public boolean alunoExistente(List<AlunoDisciplina> alunos, Long alunoId) {
		for (AlunoDisciplina alunoDisciplina : alunos) {
			if (alunoDisciplina.getIdAluno().equals(alunoId))
				return true;
		}
		return false;
	}
	
	@RequestMapping(value = "salvar-vinculo", method = RequestMethod.POST)
	public String salvarVinculo(@RequestParam(value = "aluno", required = false) Long[] alunosIds, Long id) {

		//TODO: testar
		Disciplina disc = disciplinaDAO.get(id);

		// Controlando alunos vinculados, novos alunos e alunos removidos.
		List<AlunoDisciplina> antigosVinculos = disc.getAlunos();
		List<AlunoDisciplina> alunosRemover = new ArrayList<AlunoDisciplina>();
		for (AlunoDisciplina alunoDisciplina : antigosVinculos) {
			boolean existe = false;
			for (int i = 0; i < alunosIds.length; i++) {
				if(alunosIds[i].equals(alunoDisciplina.getIdAluno())) {
					existe = true;
					break;
				}
			}
			
			if(!existe) {
				alunosRemover.add(alunoDisciplina);
			}
			
		}
		
		antigosVinculos.removeAll(alunosRemover);

		for (int i = 0; i < alunosIds.length; i++) {
			if(!alunoExistente(antigosVinculos, alunosIds[i])) {
				AlunoDisciplina alunoDisciplina = new AlunoDisciplina();
				alunoDisciplina.setIdAluno(alunosIds[i]);
				antigosVinculos.add(alunoDisciplina);
			}

		}
		disc.setAlunos(antigosVinculos);
		disciplinaDAO.put(disc);

		List<Aula> aulas = aulaDAO.getAll();

		for (Aula aula : aulas) {

			if (aula.getDisciplinaId().equals(disc.getId())) {
				for (int i = 0; i < alunosIds.length; i++) {
					log.debug("aluno: " + alunosIds[i] + " disc" + disc.getId());
					getAlunoPresenca(aula.getPresencas(), alunosIds[i], aula);
				}
			}

			deleteAlunoPresenca(aula.getPresencas(), alunosIds, aula);
		}

		aulaDAO.put(aulas);

		return "redirect:/web/listar-disciplinas";
	}

	@RequestMapping(value = "vincular-alunos", method = RequestMethod.GET)
	public String vincularAluno(HttpSession session, Model uiModel, Long id) {
		log.debug("vincular alunos");
		long idAluno;

		Disciplina disc = disciplinaDAO.get(id);
		List<DisciplinaAlunoForm> discAluno = new ArrayList<DisciplinaAlunoForm>();

		DisciplinaAlunoForm dA;

		Long professorId = ((Long) session.getAttribute("professorId"));
		List<Aluno> alunos = alunoDAO.listByProfessor(professorId);

		for (int i = 0; i < alunos.size(); i++) {
			idAluno = alunos.get(i).getId();
			dA = new DisciplinaAlunoForm();

			//TODO: Testar
			if (alunoExistente(disc.getAlunos(), idAluno) == true) {
				dA.setBinded(true);
			} else {
				dA.setBinded(false);
			}

			dA.setIdAluno(idAluno);
			dA.setIdDisciplina(id);
			dA.setNomeAluno(alunos.get(i).getNome());
			dA.setNomeDisciplina(disc.getNome());
			discAluno.add(dA);
		}

		uiModel.addAttribute("alunos", alunos);
		uiModel.addAttribute("vinculo", discAluno);
		uiModel.addAttribute("disciplina", disc);

		log.debug("vincular alunos fim");

		return "vincular-alunos";
	}

	@RequestMapping(value = "listar-disciplinas", method = RequestMethod.GET)
	public String listarDisciplinas(HttpSession httpSession, Model uiModel) {
		log.debug("Listar disciplinas");
		Aula aula = new Aula();
		aula.setData(new Date());
		uiModel.addAttribute("aula", aula);
		Long professorId = ((Long) httpSession.getAttribute("professorId"));
		List<Disciplina> disciplinas = disciplinaDAO.listByProfessor(professorId);
		uiModel.addAttribute("atrDisciplinas", disciplinas);
		uiModel.addAttribute("active", "disciplinas");
		return "listar-disciplinas";
	}

}
